package org.lc.platform.base.handler;

import cn.hutool.core.util.StrUtil;
import jakarta.validation.ConstraintViolationException;
import lombok.extern.slf4j.Slf4j;
import org.lc.platform.base.result.Result;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.ArrayList;
import java.util.List;

/**
 * 异常处理器
 * 处理的异常都是主动不影响正常使用的
 */
@RestControllerAdvice
@Order(Ordered.LOWEST_PRECEDENCE - 3)
@Slf4j
public class ValidExceptionHandler {
    /**
     * 处理参数验证异常
     */
    @ExceptionHandler(ConstraintViolationException.class)
    public Result<?> handlerConstraintViolationException(ConstraintViolationException e) {
        String msg = "参数错误，请重新传递";
        try {
            if (StrUtil.isNotEmpty(e.getMessage())) {
                msg = e.getMessage().split(":")[1];
            }
        } catch (Exception ignored) {
        }
        return Result.error(700, msg);
    }

    /**
     * 处理DTO 参数验证异常
     */

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result<?> validationBodyException(MethodArgumentNotValidException e) {
        BindingResult result = e.getBindingResult();
        List<String> errorsMsg = new ArrayList<>();
        if (result.hasErrors()) {
            List<ObjectError> errors = result.getAllErrors();
            errors.forEach(p -> {
                String msg = "字段:" + ((FieldError) p).getField() + ",错误:" + p.getDefaultMessage();
                errorsMsg.add(msg);
            });
        }
        return Result.error(600, String.join(";", errorsMsg));
    }

    @ExceptionHandler(BindException.class)
    public Result<?> validationException(BindException e) {
        var result = e.getBindingResult();
        var errorsMsg = new ArrayList<>();
        if (result.hasErrors()) {
            List<ObjectError> errors = result.getAllErrors();
            errors.forEach(p -> {
                String msg = "字段:" + ((FieldError) p).getField() + ",错误:" + p.getDefaultMessage();
                errorsMsg.add(msg);
            });
        }
        return Result.error(StrUtil.join(";", errorsMsg));
    }


}
